package touchtrack.model;

import java.util.LinkedList;
import java.util.List;

import touchtrack.exception.IllegalDuplicationException;
import touchtrack.exception.ItemNotFoundException;

/**
 * Database
 * 
 * Generic class for storage.
 * 
 * @author	MuMe09 team 6
 * 			http://mumetech.wordpress.com/
 */
public class Database<T>  
{
	/**
	 * Database constructor.
	 * 
	 * @post	datalist is set.
	 */
	public Database()
	{
		this.datalist = new LinkedList<T>();
	}
	
	/***************************************************************************
	 * 							DataList
	 ***************************************************************************/
	
	/**
	 * Mutator for the datalist.
	 * 
	 * @param 	item
	 * 			The item to be added.
	 * @post	If the given item does not already exist yet, then it's added.
	 * 			| this.contains(item) == true
	 * @throws  IllegalDuplicationException 
	 * 			| Thrown when the given item already exists in the database.
	 */
	public void add(T item) 
		throws IllegalDuplicationException
	{
		if(this.contains(item))
		{
			throw new IllegalDuplicationException(item.toString());
		}
		else
		{
			datalist.add(item);
		}
	}
	
	/**
	 * Inspector for the internal list.
	 * Returns a clone.
	 * 
	 * @return	A copy of the internal datalist.
	 */
	public List<T> fetchAll()
	{
		List<T> temporary = new LinkedList<T>();
		for(T temp : datalist)
		{
			temporary.add(temp);
		}
		return temporary;
	}
	
	/**
	 * Checks whether the given item exists in the database.
	 * 
	 * @param	item 			
	 * @return 	True if this database contains the given item, 
	 * 			otherwise false.
	 */
	public boolean contains(T item)
	{
		return datalist.contains(item);
	}
	
	/**
	 * Given the description of an item, this method looks up the
	 * corresponding object in the database.
	 * 
	 * @param 	description
	 * @return 	The corresponding object in the database.
	 * @throws 	ItemNotFoundException 
	 * 			Thrown when an item with the given description is not found.
	 */
	public T find(String description) 
		throws ItemNotFoundException
	{
		for (T temp : datalist)
		{
			if(temp.toString().equals(description))
			{
				return temp;
			}
		}
		
		throw new ItemNotFoundException(description);
	}

	/**
	 * Removes an item from the database, given the description of the item.
	 * 
	 * @param 	description 
	 * @post 	find(description) throws an ItemNotFoundException
	 * @throws 	ItemNotFoundException 
	 * 			Thrown when an item with the given description is not found.
	 */
	public void remove(String description) 
		throws ItemNotFoundException
	{
		T temp = find(description);
		if(temp == null)
		{
			throw new ItemNotFoundException(description);
		}
		datalist.remove(temp);
	}
	
	/**
	 * Removes an item from the database.
	 * 
	 * @param 	item
	 * @post 	contains(model) == false
	 * @throws 	ItemNotFoundException 
	 * 			Thrown when the given item is not found.
	 */
	public void remove(T item) 
		throws ItemNotFoundException
	{
		if(this.contains(item))
		{
			datalist.remove(item);
		}
		else
		{
			throw new ItemNotFoundException(item.toString());
		}
	}
	
	/**
	 * A list containing all the data.
	 */
	private List<T> datalist;
}